import { Component, OnInit, OnDestroy, Input, ViewChild, ElementRef } from '@angular/core';
import { Router } from "@angular/router";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { Subscription } from "rxjs/Subscription";
import { CmHttp } from "CmHttp";
import { SummaryNameService, SearchStockClass, LOCALSEARCH, BASEURL } from "shared";
import { WatchlistMiniService } from "./../watchlist-mini/watchlist-mini.service";

export const VTRADE = 'vtrade';
export const STOCK = 'stock';
export const LIVE = 'live';

@Component({
  selector: 'search',
  templateUrl: 'search.component.html',
  styleUrls: ['search.component.less']
})
export class SearchComponent implements OnInit, OnDestroy {
  @Input() placement: string;
  @ViewChild("searchInput") searchInputRef: ElementRef;
  searchSub: Subject<any> = new Subject<any>();
  handleResultSub = new Subject();
  // 是否显示搜索结果框
  isShowSearchList = false;
  // 当处于全屏进入搜索区域的时候，点击搜索之后再把右侧区域隐藏掉
  isSearchHide = false;
  // search input
  inputValue = "";
  // 搜索结果
  searchStocks: Array<SearchStockClass> = [];
  localDB: Array<SearchStockClass> = [];

  // 键盘支援辅助
  selectedStock: SearchStockClass;  // 选中的搜索结果
  selectedIndex: number = 1;  // 选中的搜索结果自然顺序
  enableEmptyResult = false;  // 是否启用空值结果显示

  searchSubscription: Subscription;
  keydownSubscription: Subscription;
  
  @ViewChild("searchInput") searchInput: ElementRef;

  constructor(private wls: WatchlistMiniService,private router: Router, private http: CmHttp, private sns: SummaryNameService) {
    sns.summaryNameSub.subscribe((res: Array<SearchStockClass>) => {
      this.localDB = res;
      // console.debug('%c LocalDB: ', 'color:#F09', this.localDB);
    });

    this.wls.addStockSub.subscribe(_ => {
      this.searchInput.nativeElement.focus();
      this.isShowSearchList = true;
    });
  }

  ngOnInit() {
    // handle search result
    this.handleResultSub.subscribe((res: Array<SearchStockClass>) => {
      switch (this.placement) {
        case VTRADE:
          this.searchStocks = res.filter(stock => stock.market.indexOf('MRI') === -1 && stock.market.indexOf('XBHS') === -1);
          break;
        case STOCK:
        default:
          this.searchStocks = res;
          break;
      }

      // 启用无结果提示
      this.enableEmptyResult = true;
      if (this.searchStocks.length) {
        this.selectedIndex = 1;
        this.selectedStock = this.searchStocks[0];
      } else {
        this.selectedIndex = 0;
        this.selectedStock = null;
      }
    });

    // search action
    this.searchSubscription = this.searchSub
      // .debounceTime(200)
      .distinctUntilChanged()
      .map(input => {
        // let a = input.match(/[a-zA-Z0-9\.]{1,}/g);  // 字母数字和. for online search
        let a = input.match(/[\u4e00-\u9fa5a-zA-Z0-9\.]{1,}/g);  // 中文,字母,数字和.
        return a ? a[0] : a;
      })
      .subscribe(value => {
        if (!value) {
          return false;
        }

        // uppercase for abbr search
        let keyword = value.toUpperCase();
        // console.log("search keyword: ", keyword);
        if (LOCALSEARCH === "enable") {
          let results = [];
          let count = 0, limitLine = 10;

          // 增加自定义快捷键
          if (keyword == '03') {
            results.push({market: "HOT_KEY", symbol: "03", name: "上证指数", abbr: "000001_SS"});
          } else if (keyword == '04') {
            results.push({market: "HOT_KEY", symbol: "04", name: "深证成指", abbr: "399001_SZ"});
          } else if (keyword == '05') {
            results.push({market: "HOT_KEY", symbol: "05", name: "分时/日K", abbr: "toggle_k"});
          }

          // local search
          this.localDB.forEach((v, i) => {
            if (count > limitLine - 1) {
              return;
            }
            try {
              if (v.symbol.indexOf(keyword) >= 0 ||
                (v.abbr && v.abbr.indexOf(keyword) >= 0) ||
                (v.name && v.name.indexOf(keyword) >= 0)
              ) {
                results.push(v);
                count++;
              }
            } catch (e) {
              console.error('input value indexOf summary:', e);
            }
          });
          // console.log("search results: ", results);
          this.handleResultSub.next(results);
        } else {
          // online search
          this.http.get(`${BASEURL}/stock/search?key=${keyword}`, {})
            .subscribe(res => {
              console.log("online search results: ", res);
              this.handleResultSub.next(res);
            });
        }
      });

    // 响应全局的keydown事件
    this.keydownSubscription = Observable.fromEvent(window, "keydown").subscribe((e: KeyboardEvent) => {
      // console.log('keyboardInput event: ', e, e.keyCode, this.isShowSearchList, this.searchStocks.length, this.enableEmptyResult);
      // 搜索结果框开启时，禁用输入框的上下左右移动操作
      if (this.isShowSearchList && this.searchStocks.length) {
        // 高亮上一条搜索结果记录, up
        if (e.key === "ArrowUp" || e.key === "PageUp" || e.key === "ArrowLeft" || e.key === "-") {
          if (this.selectedIndex) {
            if (this.selectedIndex > 1) {
              this.selectedIndex--;
              this.selectedStock = this.searchStocks[this.selectedIndex - 1];
            }
          }
          e.preventDefault();
        }
        // 高亮下一条搜索结果记录, down
        if (e.key === "ArrowDown" || e.key === "PageDown" || e.key === "ArrowRight" || e.key === "=" || e.key === "+") {
          if (this.selectedIndex < this.searchStocks.length) {
            this.selectedIndex++;
            this.selectedStock = this.searchStocks[this.selectedIndex - 1];
          }
          e.preventDefault();
        }

        // 选取当前的搜索结果, enter
        if (this.searchStocks.length && e.key === "Enter" && !e.ctrlKey && !e.metaKey) {
          if (!this.selectedStock) {
            this.selectedStock = this.searchStocks[0];
          }
          this.selectSymbol(this.selectedStock);
        }
      }

      // 模态框打开, 或者处于input, textarea焦点则不检测键盘事件
      if (document.body.classList.contains('modal-open') ||
        document.activeElement.tagName === 'INPUT' ||
        document.activeElement.tagName === 'TEXTAREA') {
        return;
      }

      // 搜索结果关闭时启用全局搜索
      if (!this.isShowSearchList) {
        if ((e.keyCode >= 48 && e.keyCode <= 57 && !e.shiftKey && !e.ctrlKey && !e.altKey) ||  // 0 - 9 and unshifted and unctrled and unalt
          (e.keyCode >= 65 && e.keyCode <= 90 && !e.shiftKey && !e.ctrlKey && !e.altKey) ||  // a - z and unshifted and unctrled and unalt
          (e.keyCode >= 96 && e.keyCode <= 105 && !e.shiftKey && !e.ctrlKey && !e.altKey) ||  // 0 - 9 for number pad unshifted and unctrled and unalt
          (e.key === ".")  // . and unshifted
        ) {
          this.searchInputRef.nativeElement.focus();
        }

        // if (e.keyCode === 8 || e.keyCode === 46) {  // Backspace, delete
        //   this.searchInputRef.nativeElement.focus();
        // }
      }
    });
  }

  ngOnDestroy() {
    this.searchSubscription ? this.searchSubscription.unsubscribe() : null;
    this.keydownSubscription ? this.keydownSubscription.unsubscribe() : null;
  }

  // 隐藏搜索结果栏
  hideList(val: string) {
    let a = val.match(/[\u4e00-\u9fa5a-zA-Z0-9\.]{1,}/g);  // 中文,字母,数字和.
    let valid = a ? a[0] : "";
    if (!valid) {
      // console.debug("hide list empty: ", val);
      setTimeout(_ => {
        this.isShowSearchList = false;
      }, 300);
    }
  }

  // 动态更新 for ngModelChange
  onDataChange(val: string) {
    // console.debug("on Data change value: ", val);

    if (val) {
      this.isShowSearchList = true;
      this.searchSub.next(val);
      let iconRight = document.getElementsByClassName("icon-right"); 
      // search focus
      if (iconRight[0] && iconRight[0].parentNode.className !== "drawer-toggle") {
        this.isSearchHide = false;
      } else {
        this.showRight();
      }
    } else {
      this.isShowSearchList = false;
    }
  }

  // 跳转到对应的个股页面
  selectSymbol(stock: SearchStockClass) {
    // console.log('terminal select symbol: ', stock);
    this.enableEmptyResult = false;
    this.isShowSearchList = false;
    if (this.isSearchHide === true) {
      let iconRight = document.getElementsByClassName("icon-right");
      iconRight[0].click();
      // this.isSearchHide = false;
    }

    // clear result
    this.searchInputRef.nativeElement.value = "";
    // this.searchStocks = [];

    // 处理自定义快捷键
    if (stock.market == "HOT_KEY") {
      if (stock.symbol == '05') {
        this.tempToggleKlineTrend();
      } else {
        this.router.navigate(["stock", stock.abbr]);
      }
      return;
    }

    // navigate stock
    let symbol = stock.symbol;
    switch (this.placement) {
      case VTRADE:
        this.router.navigate(["/vtrade", symbol.replace(".", "_")]);
        break;
      case STOCK:
      default:
        let regex = /\/stock\/.+\/f10\/(.[^/]*)/g;
        const croute = regex.exec(this.router.url);
        // console.debug('childRoute: ', croute);
        if (croute) {
          // this.router.navigate(["stock", symbol.replace(".", "_"), "f10"]);
          this.router.navigateByUrl(`/stock/${symbol.replace(".", "_")}/f10/${croute[1]}`);
        } else {
          this.router.navigate(["stock", symbol.replace(".", "_")]);
        }
        break;
    }
  }

  tempToggleKlineTrend() {
    let node = document.querySelectorAll(".kchart-tabs");
    if (node[0] && node[0].children[0] && node[0].children[0].children) {
      let nodes = node[0].children[0].children;
      let anchorDay;
      let anchorTime;
      for (let i = 0 ; i < nodes.length; i++) {
        if (nodes[i].innerText.indexOf("分时") > 0) {
            if (nodes[i] && nodes[i].children)
              anchorTime = nodes[i].children[0];
        }
        if (nodes[i].innerText.substring(0, 1) === "日") {
            if (nodes[i] && nodes[i].children)
              anchorDay = nodes[i].children[0];
        }
      }
      if (anchorDay && anchorDay.className.indexOf(" active") > 0) {
        anchorTime && anchorTime.click();
      } else {
        anchorDay && anchorDay.click();
      }
    }
  }

  showRight() {
    let that = this;
    let input = document.querySelectorAll(".search-input");
    let iconRight = document.getElementsByClassName("icon-right");
    if (iconRight[0] && iconRight[0].parentNode.className === "drawer-toggle") {
      that.isSearchHide = true;
      iconRight[0].click();
    }
  }

}